using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http;
using System.Reflection;
using Newtonsoft.Json;
using Models;
using Models.ServerModels;
using Microsoft.Win32;
using AutoUpdaterDotNET;

namespace Client
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        private bool isInitializing = true;
        private bool appExit = false;

        #region 窗口显示

        private void App_Show(object sender, EventArgs e)
        {
            trayIcon.Visible = true;
            Cfg.GetConfig();
            bsConfig.DataSource = Cfg.Configs;
            InitDgv();
            if (Cfg.Configs.RunToTray)
            {
                Visible = false;
            }
            AutoStart(Cfg.Configs.AutoRun);
            bsConfig.ResetBindings(false);
            isInitializing = false;
            Task tsk = new Task(UpdateRecordTask);
            tsk.Start();
            Timer updateTimer = new Timer();
            updateTimer.Interval = 60000;
            updateTimer.Tick += UpdateTimer_Tick;
            updateTimer.Enabled = true;
            updateTimer.Start();
        }

        private void UpdateTimer_Tick(object sender, EventArgs e)
        {
            AutoUpdater.ApplicationExitEvent += AutoUpdater_ApplicationExitEvent;
            AutoUpdater.CheckForUpdateEvent += AutoUpdater_CheckForUpdateEvent;
            AutoUpdater.ShowSkipButton = false;
            AutoUpdater.ShowRemindLaterButton = false;
            AutoUpdater.Mandatory = true;
            AutoUpdater.Start($"{Cfg.ServerAddr}Ver/DdnsUpdate.xml");
        }

        private void AutoUpdater_CheckForUpdateEvent(UpdateInfoEventArgs args)
        {
            if (args is null)
            {
                tbxLog.AppendText("检查更新失败");
                return;
            }
            if (args.IsUpdateAvailable)
            {
                appExit = true;
                AutoUpdater.DownloadUpdate();
                Application.Exit();
            }
        }

        private void AutoUpdater_ApplicationExitEvent()
        {
            appExit = true;
            Application.Exit();
        }

        private void InitDgv()
        {
            if (dgv.Columns.Count < 1)
            {
                dgv.Columns.Clear();
                dgv.Columns.Add("AccId", "账户ID");
            }
            dgv.Columns[0].Width = 350;
            dgv.Rows.Clear();
            for (int i = 0; i < Cfg.Configs.Accounts.Count; i++)
            {
                dgv.Rows.Add(new object[] { Cfg.Configs.Accounts[i] });
            }
        }

        #endregion 窗口显示

        #region 窗口关闭

        private void App_Exit(object sender, FormClosingEventArgs e)
        {
            if (Cfg.Configs.CloseToTray && appExit == false)
            {
                Visible = false;
                e.Cancel = true;
                return;
            }
            trayIcon.Visible = false;
        }

        #endregion 窗口关闭

        #region 点退出菜单

        private void Menu_Exit_Clicked(object sender, EventArgs e)
        {
            trayIcon.Visible = false;
            appExit = true;
            Application.Exit();
        }

        #endregion 点退出菜单

        #region 显示/隐藏菜单点击

        private void Menu_ShowHide_Clicked(object sender, EventArgs e)
        {
            Visible = !Visible;
            if (Visible)
                WindowState = FormWindowState.Normal;
        }

        #endregion 显示/隐藏菜单点击

        #region 提交更新请求

        private void UpdateRecord()
        {
            try
            {
                using (HttpClient hc = new HttpClient())
                {
                    hc.DefaultRequestHeaders.Add("Accept", "application/json");
                    for (int i = 0; i < Cfg.Configs.Accounts.Count; i++)
                    {
                        Dictionary<string, object> dc = new Dictionary<string, object>();
                        dc["userId"] = Cfg.Configs.Accounts[i];
                        string data = JsonConvert.SerializeObject(dc);
                        HttpContent content = new StringContent(data, Encoding.UTF8, "application/json");
                        content.Headers.Add("ContentType", "application/json;charset=utf-8");
                        var rst = hc.PostAsync($"{Cfg.ServerAddr}Ddns/UpdateDomain", content).Result;
                        if (rst.IsSuccessStatusCode)
                        {
                            var retResult = rst.Content.ReadAsStringAsync().Result;
                            RetModel msg = JsonConvert.DeserializeObject<RetModel>(retResult);
                            Invoke(new MethodInvoker(() =>
                            {
                                if (Cfg.Configs.Log)
                                    tbxLog.AppendText(msg.Success ? "提交成功,信息:" + msg.Message + Environment.NewLine : "提交信息失败，Code:" + msg.ErrCode + " Error:" + msg.Message + Environment.NewLine);
                            }));
                        }
                        else
                        {
                            Invoke(new MethodInvoker(() =>
                            {
                                if (Cfg.Configs.Log)
                                    tbxLog.AppendText("提交失败,状态码:" + rst.StatusCode.ToString() + Environment.NewLine);
                            }));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (Cfg.Configs.Log)
                    Invoke(new MethodInvoker(() =>
                        {
                            tbxLog.AppendText(ex.Message + Environment.NewLine);
                        }));
            }
        }

        #endregion 提交更新请求

        #region 增加账户

        private void btnAddAccount_Click(object sender, EventArgs e)
        {
            try
            {
                if (tbxAccId.Text == "")
                    throw new Exception("账户ID必须填写！");
                if (Cfg.Configs.Accounts.Contains(tbxAccId.Text))
                    throw new Exception("账户已经存在！");
                Cfg.Configs.Accounts.Add(tbxAccId.Text);
                Cfg.SaveConfig();
                InitDgv();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion 增加账户

        #region 删除账户

        private void btnDelAccount_Click(object sender, EventArgs e)
        {
            try
            {
                if (dgv.SelectedRows.Count < 1)
                    throw new Exception("必须选择一个要删除的账户");
                string tmp = dgv.Rows[dgv.SelectedRows[0].Index].Cells[0].Value.ToString();
                if (string.IsNullOrEmpty(tmp))
                    throw new Exception("选择的记录不正确！");
                Cfg.Configs.Accounts.Remove(tmp);
                Cfg.SaveConfig();
                InitDgv();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion 删除账户

        #region 开机启动

        private void AutoStart(bool t)
        {
            try
            {
                string regStr = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
                RegistryKey machine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32);
                RegistryKey run = machine.OpenSubKey(regStr, true);
                var keys = run.GetSubKeyNames();
                Action create_registry = new Action(() =>
                {
                    run.CreateSubKey("LNDdnsClient", RegistryKeyPermissionCheck.Default);
                    run.SetValue("LNDdnsClient", Application.ExecutablePath);
                });
                Action modify_registry = new Action(() =>
                  {
                      bool finded = false;
                      foreach (var item in keys)
                      {
                          if (item == "LNDdnsClient")
                          {
                              run.SetValue("LNDdnsClient", Application.ExecutablePath);
                              finded = true;
                              break;
                          }
                      }
                      if (!finded)
                          create_registry();
                  });
                Action del_registry = new Action(() =>
                  {
                      foreach (var item in keys)
                      {
                          if (item == "LNDdnsClient")
                          {
                              run.SetValue(item, "");
                              run.DeleteSubKey(item, false);
                              break;
                          }
                      }
                  });
                if (t)
                {
                    if (keys != null)
                        modify_registry();
                    else
                        create_registry();
                }
                else
                {
                    if (keys != null)
                        del_registry();
                }
                run.Close();
                machine.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion 开机启动

        private void bsConfig_ListChanged(object sender, ListChangedEventArgs e)
        {
            if (isInitializing)
                return;
            Cfg.SaveConfig();
            AutoStart(Cfg.Configs.AutoRun);
        }

        #region 提交请求

        private void UpdateRecordTask()
        {
            while (!appExit)
            {
                try
                {
                    UpdateRecord();
                }
                catch (Exception ex)
                {
                    Invoke(new MethodInvoker(() =>
                    {
                        tbxLog.AppendText(ex.Message);
                    }));
                }
                System.Threading.Thread.Sleep(30000);
            }
        }

        #endregion 提交请求
    }
}